`ifndef MY_ENV_SVH
`define MY_ENV_SVH
class my_env extends uvm_env;
    
//    my_driver drv;
//    my_monitor i_mon;
//    my_monitor o_mon;

    my_agent i_agt;
    my_agent o_agt;
    my_model mdl;
    my_scoreboard scb;

    uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;
    uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;
    uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;

    function new(string name = "my_env", uvm_component parent);
        super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
//        drv = my_driver::type_id::create("drv", this);
//        i_mon = my_monitor::type_id::create("i_mon", this);
//        o_mon = my_monitor::type_id::create("o_mon", this);
        i_agt = my_agent::type_id::create("i_agt", this);
        o_agt = my_agent::type_id::create("o_agt", this);
        mdl = my_model::type_id::create("mdl", this);
        scb = my_scoreboard::type_id::create("scb", this);
        i_agt.is_active = UVM_ACTIVE;
        o_agt.is_active = UVM_PASSIVE;

        agt_mdl_fifo = new("agt_mdl_fifo", this);
        agt_scb_fifo = new("agt_scb_fifo", this);
        mdl_scb_fifo = new("mdl_scb_fifo", this);

    endfunction

    function void connect_phase(uvm_phase phase);
       super.connect_phase(phase); 
       // agent and model
       // Why Not use monitor's ap directly
       i_agt.ap.connect(agt_mdl_fifo.analysis_export);
       mdl.port.connect(agt_mdl_fifo.blocking_get_export);
       // agent and scoreboard
       scb.act_port.connect(agt_scb_fifo.blocking_get_export);
       o_agt.ap.connect(agt_scb_fifo.analysis_export);
       // model and scoreboard
       mdl.ap.connect(mdl_scb_fifo.analysis_export);
       scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);
    endfunction
    // Start sequence in UVM_ENV
    //task main_phase(uvm_phase phase);
    //    my_sequence seq;
    //    phase.raise_objection(this);
    //    seq = my_sequence::type_id::create("seq");
    //    seq.start(i_agt.sqr);
    //    phase.drop_objection(this);
    //endtask
    `uvm_component_utils(my_env)
endclass 


`endif
